package org.davidliebman.android.awesomewifi;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.Uri;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.AdapterView.OnItemSelectedListener;


public class Wifi extends ListActivity  {
	private static final String TAG = "AwesomeWifi";
	public WifiManager wifi;
	private BroadcastReceiver receiver;
	private RecordAdapter mAdapter;
	private WifiInfo info;
	private LogFileManager mLogFile;
	
	private PowerManager mPM;
	private PowerManager.WakeLock mWl;
	private Button mScanButton;
	private ProgressDialog mProgress = null;
	private ThreadHelperTimer mTimer;
	private ArrayList<WifiConfiguration> mConfigs = new ArrayList<WifiConfiguration>();
	private ArrayList<WifiListNode> mList = new ArrayList<WifiListNode>();
	private int mMillisecondWait = 0; // formerly 5000 - 5 secs
	private int mSecondTimer = 20;
	private int mListPosition = -1;
	public boolean mAllowClick = false;
	public boolean mCanSelect = true;
	public boolean mCanShowStartDialog = true;
	public boolean mCanLoop = false;
	public boolean mExpressMode = true;
	public boolean mCanLogout = false;
	public boolean mShouldLogin = false;
	public boolean mAlreadyConnected = false;
	public boolean mDebug = false;
	public int mModeOfOp = 0;
	public String mCompletionMessage = new String("Finished Login.");
	public static final String NPLOG = new String("AwesomeWifi.log");
	
	public static final int MODE_CHOOSELOGIN_COMBINED = 0;
	public static final int MODE_CHOOSELOGIN_CONFIG = 1;
	public static final int MODE_CHOOSELOGIN_SCAN = 2;
	
	public static final String[] MODE_TEXT = new String[3];
	public static final String[] MODE_TEXT_LONG = new String[3];
	
	public static final int DIALOG_DONOTHING_ID = 0;
	public static final int DIALOG_AUTOLOGIN_ID = 1;
	public static final int DIALOG_NOPASSWORD_ID = 2;
//	public static final int DIALOG_ENDLOGIN_ID = 3;
	public static final int DIALOG_SHOWTOAST_ID = 4;
	public static final int DIALOG_SHOWPROGRESS_ID = 5;
	public static final int DIALOG_STOPPROGRESS_ID = 6;
	public static final int DIALOG_CHANGEMODE_ID = 7;
	public static final int DIALOG_WIFICONFIG_ID = 8;
	public static final int DIALOG_WIFIFORGET_ID = 9;
	public static final int DIALOG_SCAN_NP_ID = 10;
	public static final int DIALOG_TIMEOUT_ID = 11;
	public static final int DIALOG_CANCELTIMER_ID = 12;
	
	
	public static final String SAVE = new String("awesomewifi_save");
	public static final String SAVED_MODEOFOP = new String("awesomewifi_modeofop");
	public static final String SAVED_ALLOWCLICK = new String ("awesomewifi_allowclick");
	public static final String SAVED_EXPRESSMODE = new String ("awesomewifi_expressmode");
	
	public static final int ENCRYPT_DETECTNONE = 0;
	public static final int ENCRYPT_WPA_WPA2 = 1;
	public static final int ENCRYPT_WEP = 2;
	public static final int ENCRYPT_NONE = 3;
	
	/* used for encryption configuration dialog options */
	private int mEncryptionScheme = 0;
	private String mRawSSID = new String("");
	private boolean mLongMode = false;
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		//get saved progress dialog
		mProgress = (ProgressDialog) getLastNonConfigurationInstance();
		
		//get saved preferences
		this.loadPreferences();
		
		setStatusLineVars();
				
		// setup Log File
		mLogFile = new LogFileManager (NPLOG, mDebug);
		mLogFile.insertDate(this);
		
		// Setup WiFi
		wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
		
		mCanLoop = true;
		
		// Get WiFi status
		// List available networks		
		updateStatusLine();

		mPM = (PowerManager) getSystemService(Context.POWER_SERVICE);
		mWl = mPM.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, TAG);
		
        ListView lv = getListView();
        lv.setTextFilterEnabled(true);
        registerForContextMenu(lv);
        lv.setOnItemClickListener(new OnItemClickListener () {
        	
        	@Override
        	 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        		if (mCanSelect == true && mAllowClick) {
        			Toast.makeText(Wifi.this, "LONG PRESS FOR OPTIONS", Toast.LENGTH_LONG).show();
        		}

        	 }
        });
        
  
        
		// Register Broadcast Receiver
		if (receiver == null)
			receiver = (BroadcastReceiver)new WiFiScanReceiver(this);

		IntentFilter mIntentFilter = new IntentFilter();
		mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
		mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
		mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
		mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
		mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
		registerReceiver(receiver,mIntentFilter);
		

		mScanButton = (Button) findViewById(R.id.buttonScan);
	    mScanButton.setOnClickListener(new OnClickListener() {
	        public void onClick(View v) {
	        	


	    		if (v.getId() == R.id.buttonScan) {
	    			
	    			wifi.startScan();
	    			
	    			mCanShowStartDialog = false;
	    			
	    			mModeOfOp = mModeOfOp + 1;
	    			if (mModeOfOp >= 3) mModeOfOp = 0;
	    			
	    			updateStatusLine();
	    			savePreferences();


	    			
	    		}
	        }
	    });
	}

	

	@Override
	public void onPause() {
		this.mCanLoop = false;
		unregisterReceiver(receiver);
		savePreferences();
		super.onPause();
	}

	@Override
	public void onResume() {
		super.onResume();
		
		this.mCanShowStartDialog = true;
		this.mCanLoop = true;
		
		/* set up broadcast receiver */
		if (receiver == null)
			receiver = (BroadcastReceiver)new WiFiScanReceiver(this);

		IntentFilter mIntentFilter = new IntentFilter();
		mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
		mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
		mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
		mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
		mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
		registerReceiver(receiver,mIntentFilter);
	
		/* load preferences */
		loadPreferences();
		
		/* wifi start scan */
		wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
		
		wifi.startScan();
		
		/* logfile */
		mLogFile = new LogFileManager(NPLOG, mDebug);
		mLogFile.insertDate(this);
		
		/* list adapters */
		updateStatusLine();
		
		
	}
	
	@Override
	public Object onRetainNonConfigurationInstance() {
		final ProgressDialog data = this.mProgress;
		return data;
	}
	
	public Handler mHandler = new Handler() {
		
		
    	public void handleMessage(Message msg) {
    		
    		updateStatusLine();
    		
    		switch(msg.what){
    		   case Wifi.DIALOG_DONOTHING_ID:
    			   break;
    		   
    		   case Wifi.DIALOG_SHOWTOAST_ID:
    			   String mTestString =(String) msg.obj;
    			   Toast.makeText(Wifi.this, mTestString,
    	    				Toast.LENGTH_LONG).show();
    			   mLogFile.appendToLog(mTestString);
    			   break;
    		   case Wifi.DIALOG_SHOWPROGRESS_ID:
    			   mWl.acquire();
    			   mProgress = ProgressDialog.show(Wifi.this, "", 
                           "Connecting. Please wait...", true);
    			   break;
    		   case Wifi.DIALOG_STOPPROGRESS_ID:
    			   if (mProgress != null) mProgress.dismiss();
    			   if (mWl.isHeld()) mWl.release();
    			   break;
    		   case Wifi.DIALOG_CHANGEMODE_ID:
    			   mModeOfOp = (Integer)msg.obj;
    			   break;
    		  
    		   case Wifi.DIALOG_TIMEOUT_ID:
    			   showDialog(Wifi.DIALOG_TIMEOUT_ID);
    			   break;
    		   case Wifi.DIALOG_CANCELTIMER_ID:
    			   if (mTimer != null && !mTimer.isCancelled()) {
    				   mTimer.cancel(true);
    			   }
    			   break;
    		   }
    		
    		
    		super.handleMessage(msg);
    	}
	};
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflate = getMenuInflater();
		inflate.inflate(R.menu.main_menu, menu);
		
		//
		return true;
	}
	
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		
		/* set radio buttons for 'allow click' */
		if (!menu.findItem(R.id.menu_set_allowclick).isChecked() && 
				!menu.findItem(R.id.menu_clear_allowclick).isChecked()) {
			
			if (this.mAllowClick) menu.findItem(R.id.menu_set_allowclick).setChecked(mAllowClick);
			else menu.findItem(R.id.menu_clear_allowclick).setChecked(!mAllowClick);
		
		}
		
		/* set radio buttons for 'express mode' */
		if (!menu.findItem(R.id.menu_set_express).isChecked() && 
				!menu.findItem(R.id.menu_clear_express).isChecked()) {
			
			if (this.mExpressMode) menu.findItem(R.id.menu_set_express).setChecked(mExpressMode);
			else menu.findItem(R.id.menu_clear_express).setChecked(!mExpressMode);

		}
		
		
		return super.onPrepareOptionsMenu(menu);
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		
		switch(item.getItemId()) {
		case R.id.menu_set_express :
			
			if (!item.isChecked()) {

				item.setChecked(true);
				this.mExpressMode = true;
				
				//showDialog(Wifi.DIALOG_AUTOLOGIN_ID);
			}
			this.updateStatusLine();
			
			break;
		case R.id.menu_clear_express :
			
			if (!item.isChecked()) {

				item.setChecked(true);
				this.mExpressMode = false;
			}
			
			this.updateStatusLine();
			break;
		
		case R.id.menu_set_allowclick :
			
			if (!item.isChecked()) {

				item.setChecked(true);
				this.mAllowClick = true;
			}
			
			break;
			
		case R.id.menu_clear_allowclick :
			
			if (!item.isChecked()) {

				item.setChecked(true);
				this.mAllowClick = false;
			}
			
			break;
		
		
		case R.id.menu_clear_all_config :
			
			wifi.disableNetwork(info.getNetworkId());
			
			wifi.disconnect();
			updateStatusLine();
			break;
		
		case R.id.menu_new_config_item :
			this.mListPosition = -1;
			showDialog(Wifi.DIALOG_WIFICONFIG_ID);
			
			break;
		}
		
		this.savePreferences();
		return true;
	}
	
	@Override
	public void onCreateContextMenu (ContextMenu menu, View mV, ContextMenuInfo mMenuInfo) {
		super.onCreateContextMenu(menu, mV, mMenuInfo);
		if ( mCanSelect && mAllowClick ) {
			MenuInflater mInflater = getMenuInflater();
			mInflater.inflate(R.menu.context_menu, menu);
			
			AdapterView.AdapterContextMenuInfo mInfo = (AdapterView.AdapterContextMenuInfo) mMenuInfo;
			WifiListNode mNode = mList.get(mInfo.position);
			switch (mNode.getContents()) {
			case WifiListNode.CONTAINS_BOTH :
				menu.findItem(R.id.context_menu_config).setVisible(false);
				menu.findItem(R.id.context_menu_config).setEnabled(false);
				
				break;
			case WifiListNode.CONTAINS_CONFIG :
				menu.findItem(R.id.context_menu_connect).setVisible(false);
				menu.findItem(R.id.context_menu_connect).setEnabled(false);
				
				menu.findItem(R.id.context_menu_config).setVisible(false);
				menu.findItem(R.id.context_menu_config).setEnabled(false);
				
				menu.findItem(R.id.context_menu_dis).setVisible(false);
				menu.findItem(R.id.context_menu_dis).setEnabled(false);
				break;
			case WifiListNode.CONTAINS_SCANS :
				menu.findItem(R.id.context_menu_forget).setVisible(false);
				menu.findItem(R.id.context_menu_forget).setEnabled(false);
				
				menu.findItem(R.id.context_menu_dis).setVisible(false);
				menu.findItem(R.id.context_menu_dis).setEnabled(false);
				
				// connect directly if no encryption:
				if (mNode.getEncryption() != Wifi.ENCRYPT_DETECTNONE) {
					menu.findItem(R.id.context_menu_connect).setVisible(false);
					menu.findItem(R.id.context_menu_connect).setEnabled(false);
				}
				break;
			
			}
			// 'dissasociate' menu:
			if (mNode.getContents() != WifiListNode.CONTAINS_SCANS && 
					wifi.getConnectionInfo().getNetworkId() != mNode.getConfig().networkId){
				menu.findItem(R.id.context_menu_dis).setVisible(false);
				menu.findItem(R.id.context_menu_dis).setEnabled(false);
			}
	
				
		}
	}
	
	@Override
	public boolean onContextItemSelected (MenuItem mItem) {
		AdapterContextMenuInfo mInfo = (AdapterContextMenuInfo) mItem.getMenuInfo();
		mListPosition = -1;
		
		switch (mItem.getItemId()) {
		case R.id.context_menu_connect :
			if ( mCanSelect   && mAllowClick) {
				final int position = mInfo.position;
    			ThreadHelper mHelper = new ThreadHelper();
    			mHelper.execute(new Integer[] {position	});
    		
    		}
			break;
		case R.id.context_menu_config :
			this.mListPosition = mInfo.position;
			//NOTE: 'CONTAINS_SCANS' means not 'CONTAINS_BOTH' so is not configured already
			if (mList.get(mListPosition).getContents() == WifiListNode.CONTAINS_SCANS) {
				showDialog(Wifi.DIALOG_WIFICONFIG_ID);
			}
			else {
				this.toastFromThread("Cannot Config This Listing. \nAlready Configured.");
			}
			
			break;
		case R.id.context_menu_forget :
			this.mListPosition = mInfo.position;
			//NOTE: could be 'CONTAINS_CONFIG' or 'CONTAINS_BOTH'
			if (mList.get(mListPosition).getContents() != WifiListNode.CONTAINS_SCANS) {
				showDialog(Wifi.DIALOG_WIFIFORGET_ID);
			}
			else {
				this.toastFromThread("Cannot Forget This Listing. \nThis Is A Scan Result.");
			}
			break;
		case R.id.context_menu_dis :
			this.mListPosition = mInfo.position;
			if (mList.get(mListPosition).getContents() == WifiListNode.CONTAINS_BOTH ) {
				if (wifi.getConnectionInfo().getNetworkId() == mList.get(mListPosition).getConfig().networkId){
					wifi.disableNetwork(mList.get(mListPosition).getConfig().networkId);
					wifi.disconnect();
					updateStatusLine();
				}
				else {
					this.toastFromThread("Cannot Disassociate This Listing. \nThis is not Associated");
				}
				
			}		
			else {
				this.toastFromThread("Cannot Disassociate This Listing.");//
			}
			break;
		}
		
		return super.onContextItemSelected(mItem);
	}
	
	
	
	protected Dialog onCreateDialog(int id) {
	    Dialog dialog;
	    AlertDialog.Builder builder;
    	AlertDialog alertDialog;

    	Context mContext;
    	mContext = this;
    	LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
    	View layout;
    	TextView text;
    	ImageView image;
    	String mPositive, mNegative;
    	
	    switch(id) {

	   
	   
	    ////////////////////////////////
	    case Wifi.DIALOG_WIFICONFIG_ID :
	    	
	    	this.mCanShowStartDialog = false;
	    	WifiListNode mNode = new WifiListNode();
	    	if (mListPosition != -1) {
	    		mNode = mList.get(mListPosition);
	    	}
	    	
	    	layout = inflater.inflate(R.layout.congrats_wifi_password,
	    			(ViewGroup) findViewById(R.id.layout_root));
	    		
	    	final Spinner mSpinner = (Spinner) layout.findViewById(R.id.spinner_encryption);
    	    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
    	            this, R.array.encryption_array, android.R.layout.simple_spinner_item);
    	    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    	    mSpinner.setAdapter(adapter);
    	    
	    	text = (TextView) layout.findViewById(R.id.congrats_text);

    	    
    	    mLongMode = false;
	    	String mDescription = new String("Enter Desired Scheme:");
	    	mRawSSID = new String("");
	    	mEncryptionScheme = 0;
	    	
	    	final EditText mWifiSSID = (EditText)layout.findViewById(R.id.edit_ssid);
	    	final EditText mWifiPassword = (EditText)layout.findViewById(R.id.edit_password);
	    	
	    	if (this.mListPosition == -1 ) {
	    		mLongMode = true;
	    	}
	    	else if(mNode.getEncryption() == Wifi.ENCRYPT_DETECTNONE ) {
	    		
	    		mWifiSSID.setText(mNode.getScan().SSID);
	    		mRawSSID = mNode.getScan().SSID;
	    		mLongMode = true;
	    	}
	    	else {
	    		((TextView) layout.findViewById(R.id.textViewSSID)).setVisibility(View.GONE);
	    		((EditText)layout.findViewById(R.id.edit_ssid)).setVisibility(View.GONE);
	    		((Spinner)layout.findViewById(R.id.spinner_encryption)).setVisibility(View.GONE);
	    		((TextView)layout.findViewById(R.id.textViewEncryption)).setVisibility(View.GONE);
	    		mDescription = mNode.getDescription();
	    		mRawSSID = mNode.getScan().SSID;
	    		mEncryptionScheme = mNode.getEncryption();
	    	}
	    	
	    	if (!mLongMode) {
	    		text.setText("Wifi Config For: \n\"" + mRawSSID + "\"\n"+ mDescription);
	    	}
	    	else {
	    		text.setText("Wifi Config.\n"+mDescription);
	    	}
	    	
	    	image = (ImageView) layout.findViewById(R.id.image);
	    	image.setImageResource(R.drawable.ic_launcher);
	    	
	    	
	    	mWifiSSID.setOnFocusChangeListener( new OnFocusChangeListener() {
	    		@Override
	    		public void onFocusChange(View v, boolean hasFocus) {
	    			if (hasFocus) {
	    				mWifiSSID.setText("");
	    			}
	    		}
	    	});
	    	
	    	mWifiPassword.setOnFocusChangeListener(new OnFocusChangeListener() {	
				@Override
				public void onFocusChange(View v, boolean hasFocus) {
					if (hasFocus) {
						mWifiPassword.setText("");
					}
				}
	    	});
	    	
	    	mSpinner.setOnItemSelectedListener(new OnItemSelectedListener () {
	    		
	    		@Override
	    		public void onItemSelected(AdapterView<?> parent,
	    				View view, int pos, long id) {
	    			
	    			//NOTE: these values are hard coded to match strings.xml...
	    			switch (pos) {
	    			case 0: mEncryptionScheme = Wifi.ENCRYPT_NONE; break;
	    			case 1: mEncryptionScheme = Wifi.ENCRYPT_WPA_WPA2; break;
	    			case 2: mEncryptionScheme = Wifi.ENCRYPT_WEP; break;
	    			}
	    		}

	    		public void onNothingSelected(AdapterView parent) {
	    			// Do nothing.
	    			mEncryptionScheme = Wifi.ENCRYPT_NONE;
	    		}

	    	});
	    	
	    	mPositive = new String("Record Info.");
	    	mNegative = new String("Return To App.");
	    	
	    	builder = new AlertDialog.Builder(this);
	    	builder.setView(layout);
	    	builder.setCancelable(false)
    	       .setPositiveButton(mPositive, new DialogInterface.OnClickListener() {
    	           public void onClick(DialogInterface dialog, int id) {
    	        	   if (mLongMode) mRawSSID = mWifiSSID.getText().toString();
    	        	   if (mRawSSID.length() != 0 ) {
    	        		   WifiConfiguration mConfig = makeWifiConfig(mEncryptionScheme , 
    	        				   mRawSSID, mWifiPassword.getText().toString());
    	        		   menuHelperSmartAddConfig(mConfig);
    	        	   }
    	        	   dialog.cancel();
    	        	   removeDialog(Wifi.DIALOG_WIFICONFIG_ID);
    	        	   
    	           }
    	       })
    	       .setNegativeButton(mNegative, new DialogInterface.OnClickListener() {
    	           public void onClick(DialogInterface dialog, int id) {
    	                
    	        	    dialog.cancel();
    	                removeDialog(Wifi.DIALOG_WIFICONFIG_ID);
    	           }
    	       });
	    	
	    	alertDialog = builder.create();
	    	
	    	dialog = (Dialog) alertDialog;
	    	break;
	    ////////////////////////////////
	    case Wifi.DIALOG_WIFIFORGET_ID :
	    	
	    	if (mListPosition != -1) {
	    		mNode = mList.get(mListPosition);
	    	}
	    	
	    	layout = inflater.inflate(R.layout.congrats,
	    			(ViewGroup) findViewById(R.id.layout_root));
	    	
	    	text = (TextView) layout.findViewById(R.id.congrats_text);
	    	text.setText("Delete Wifi Config " + mList.get(mListPosition).getConfig().SSID);
	    	
	    	image = (ImageView) layout.findViewById(R.id.image);
	    	image.setImageResource(R.drawable.ic_launcher);
	    	mPositive = new String("Delete.");
   	    	mNegative = new String("Cancel.");
	    	builder = new AlertDialog.Builder(this);
	    	builder.setView(layout);
	    	builder.setCancelable(false)
    	       .setPositiveButton(mPositive, new DialogInterface.OnClickListener() {
    	           public void onClick(DialogInterface dialog, int id) {
    	        	   dialog.cancel();
    	        	   menuHelperSmartForgetConfig(mListPosition);
    	        	   removeDialog(DIALOG_WIFIFORGET_ID);
    	        	   updateStatusLine();
    	           }
    	       })
    	       .setNegativeButton(mNegative, new DialogInterface.OnClickListener() {
    	           public void onClick(DialogInterface dialog, int id) {
    	        	   	mCanSelect = true;
    	        	   	updateStatusLine();
    	                dialog.cancel();
    	                removeDialog(DIALOG_WIFIFORGET_ID);
    	           }
    	       });
	    	
	    	alertDialog = builder.create();
	    	
	    	dialog = (Dialog) alertDialog;
	    	break;

	    ///////////////////////////////
	    default:
	        dialog = null;
	    }
	    return dialog;
	}

	public String getIpAddress() {
		info = wifi.getConnectionInfo();
		int ip = info.getIpAddress();
		return getIpAddress(ip);
	}
	
	public String getIpAddress(int ip) {
		String ipString = String.format(
				"%d.%d.%d.%d",
				(ip & 0xff),
				(ip >> 8 & 0xff),
				(ip >> 16 & 0xff),
				(ip >> 24 & 0xff));
		
		return ipString;
	}
	
	public String streamToString(InputStream mIn) {
		
		BufferedInputStream bis = new BufferedInputStream(mIn);
		ByteArrayOutputStream buf = new ByteArrayOutputStream();
		
		try{    
		    int result = bis.read();
		    while(result != -1) {
		      byte b = (byte)result;
		      buf.write(b);
		      result = bis.read();
		    }        
		
		}
		catch(Exception e) {
		    Log.e(TAG, "buffer problem");
		}
		
		return buf.toString();
	}
	
	public void loadPreferences() {
		SharedPreferences mPref = this.getSharedPreferences(SAVE, MODE_PRIVATE);
		mModeOfOp = mPref.getInt(SAVED_MODEOFOP, Wifi.MODE_CHOOSELOGIN_COMBINED);
		mAllowClick = mPref.getBoolean(SAVED_ALLOWCLICK, false);
		mExpressMode = mPref.getBoolean(SAVED_EXPRESSMODE, true);
	}
	
	public void savePreferences() {
		SharedPreferences mPref = this.getSharedPreferences(SAVE, MODE_PRIVATE);
		Editor mEditor = mPref.edit();
		mEditor.putInt(SAVED_MODEOFOP, mModeOfOp);
		mEditor.putBoolean(SAVED_ALLOWCLICK, mAllowClick);
		mEditor.putBoolean(SAVED_EXPRESSMODE, mExpressMode);
		mEditor.commit();
	}
	
	public void launchTestStringInBrowser(String mUriString) {
		Uri mUriUrl = Uri.parse(mUriString);
		Intent mLaunchBrowser = new Intent(Intent.ACTION_VIEW, mUriUrl);
		startActivity(mLaunchBrowser);
		
	}
	
	
	public void updateStatusLine() {
		this.mListPosition = -1;
		
		// Get WiFi status
		info = wifi.getConnectionInfo();
		
		if ( this.mExpressMode ) {
			this.mModeOfOp = Wifi.MODE_CHOOSELOGIN_COMBINED;
			((Button)findViewById(R.id.buttonScan)).setVisibility(View.GONE);
			((TextView)findViewById(R.id.textMode)).setVisibility(View.GONE);
		}
		else {
			((Button)findViewById(R.id.buttonScan)).setVisibility(View.VISIBLE);
			((TextView)findViewById(R.id.textMode)).setVisibility(View.VISIBLE);
		}
		
		((TextView)findViewById(R.id.textMode)).setText( MODE_TEXT_LONG[mModeOfOp]);
		((TextView)findViewById(R.id.textMode)).setTextColor(Color.WHITE);
		((TextView)findViewById(R.id.textMode)).setBackgroundColor(Color.DKGRAY);
		((TextView)findViewById(R.id.textStatus)).setText(
				"\nWiFi Status: " + info.toString() + "\n");
		((Button)findViewById(R.id.buttonScan)).setText("MODE: " + MODE_TEXT[mModeOfOp]);

		try {
			switch (mModeOfOp) {
	    	case Wifi.MODE_CHOOSELOGIN_SCAN :
	    		mCanSelect = true;
	    		mList = this.fillScanList();

	    		break;
	    	case Wifi.MODE_CHOOSELOGIN_CONFIG :
	    		mCanSelect = true;
	    		mList = this.fillConfigList();

	    		break;
	    	case Wifi.MODE_CHOOSELOGIN_COMBINED :
	    		mCanSelect = true;
	    		mList = this.fillCombinedList();

	    		break;

			}
			
			mAdapter = new RecordAdapter(this, R.layout.main, mList, 0 ,info);
    		setListAdapter(mAdapter);
    		mAdapter.notifyDataSetChanged();
    	}
		catch (Exception e) {
			Log.e(TAG, e.toString());
			return;

			
		}
	}
	
	public void setStatusLineVars() {
		
		MODE_TEXT[0] = this.getResources().getString(R.string.mode_text_0);
		MODE_TEXT[1] = this.getResources().getString(R.string.mode_text_1);
		MODE_TEXT[2] = this.getResources().getString(R.string.mode_text_2);
			
		MODE_TEXT_LONG[0] = this.getResources().getString(R.string.mode_text_long_0);
		MODE_TEXT_LONG[1] = this.getResources().getString(R.string.mode_text_long_1);
		MODE_TEXT_LONG[2] = this.getResources().getString(R.string.mode_text_long_2);
			
		
	}
	
	public WifiConfiguration makeWifiConfig(int mEncryption, String mScanSSID, String mPassword) {

		WifiConfiguration wfc = new WifiConfiguration();
		
		wfc.SSID = new String ("\"" + mScanSSID + "\"");
		wfc.status = WifiConfiguration.Status.DISABLED;
		wfc.priority = 40;
		
		switch (mEncryption) {
		
		case Wifi.ENCRYPT_NONE:
			wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
			wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
			wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
			wfc.allowedAuthAlgorithms.clear();
			wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
			wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
			wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
			wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
			wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
			wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
			break;
			
		case Wifi.ENCRYPT_WEP:
			wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
			wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
			wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
			wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
			wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
			wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
			wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
			wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
			wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

			wfc.wepKeys[0] = new String("\"" + mPassword + "\"");
			wfc.wepTxKeyIndex = 0;
	
			break;
		case Wifi.ENCRYPT_WPA_WPA2 :
			wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
			wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
			wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
			wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
			wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
			wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
			wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
			wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
			wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

			wfc.preSharedKey = new String("\"" + mPassword + "\"");

			break;
		}
		return wfc;
	}
	
	public ArrayList<WifiListNode> fillCombinedList() {
		ArrayList<WifiListNode> mList = new ArrayList<WifiListNode> ();
		mList.clear();
		wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
		ArrayList<ScanResult> mScans = (ArrayList<ScanResult>) wifi.getScanResults();
		ArrayList<WifiConfiguration> mConfigs = (ArrayList<WifiConfiguration>) wifi.getConfiguredNetworks();
		
		/* first add all configured networks */
		for (int i = 0; i < mConfigs.size(); i ++ ) {
			WifiListNode mNode = new WifiListNode(mConfigs.get(i)); 
			mList.add(mNode);
		}
		
		/* compare scans to added networks and change as necessary */
		int mListStartSize = mList.size();
		for (int i = 0; i < mScans.size(); i ++ ) {
			
			boolean mFound = false;
			for (int j = 0; j < mListStartSize; j ++ ) {
				if (mList.get(j).getContents() == WifiListNode.CONTAINS_CONFIG || 
						mList.get(j).getContents() == WifiListNode.CONTAINS_BOTH) {
					if (("\""+mScans.get(i).SSID+"\"").contentEquals(mList.get(j).getConfig().SSID)) {
						mList.get(j).setContents(WifiListNode.CONTAINS_BOTH);
						mList.get(j).setScan(mScans.get(i));
						mFound = true;
					}
				}
				
			}
			/* add un-found scans to end of list */
			if (!mFound) {
				WifiListNode mNode = new WifiListNode(mScans.get(i));
				mNode.parseScanDescription();
				mList.add(mNode);
				
			}
		}
		return mList;
	}
	public ArrayList<WifiListNode> fillScanList() {
		ArrayList<WifiListNode> mList = new ArrayList<WifiListNode> ();
		mList.clear();
		wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
		ArrayList<ScanResult> mScans = (ArrayList<ScanResult>) wifi.getScanResults();
		ArrayList<WifiConfiguration> mConfigs = (ArrayList<WifiConfiguration>) wifi.getConfiguredNetworks();

		/* add all scans to list */
		for (int i = 0; i < mScans.size(); i ++ ) {
	
			WifiListNode mNode = new WifiListNode(mScans.get(i));
			mNode.parseScanDescription();
			/* add Config info to node if it matches */
			for (int j = 0; j < mConfigs.size(); j ++ ) {
				if (mConfigs.get(j).SSID.contains(mNode.getScan().SSID)) {
					mNode.setContents(WifiListNode.CONTAINS_BOTH);
					mNode.setConfig(mConfigs.get(j));
				}
			}
			mList.add(mNode);
				
		}
		return mList;
	}
	
	public ArrayList<WifiListNode> fillConfigList() {
		ArrayList<WifiListNode> mList = new ArrayList<WifiListNode> ();
		mList.clear();
		wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
		ArrayList<WifiConfiguration> mConfigs = (ArrayList<WifiConfiguration>) wifi.getConfiguredNetworks();
		ArrayList<ScanResult> mScans = (ArrayList<ScanResult>) wifi.getScanResults();

		/* first add all configured networks */
		for (int i = 0; i < mConfigs.size(); i ++ ) {
			WifiListNode mNode = new WifiListNode(mConfigs.get(i)); 
			mList.add(mNode);
		}

		/* compare scans to added networks and change as necessary */
		int mListStartSize = mList.size();
		for (int i = 0; i < mScans.size(); i ++ ) {
			
			boolean mFound = false;
			for (int j = 0; j < mListStartSize; j ++ ) {
				if (mList.get(j).getContents() == WifiListNode.CONTAINS_CONFIG || 
						mList.get(j).getContents() == WifiListNode.CONTAINS_BOTH) {
					if (("\""+mScans.get(i).SSID+"\"").contentEquals(mList.get(j).getConfig().SSID)) {
						mList.get(j).setContents(WifiListNode.CONTAINS_BOTH);
						mList.get(j).setScan(mScans.get(i));
						mList.get(j).parseScanDescription();
						mFound = true;
					}
				}
				
			}
	
		}
		return mList;
	}
	
	public void chooseNetId(int position) {
		// this is used when CHOOSELOGIN is the mode. 
		wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
		

		switch (mModeOfOp) {
    	case Wifi.MODE_CHOOSELOGIN_SCAN :
    	case Wifi.MODE_CHOOSELOGIN_CONFIG :
    	case Wifi.MODE_CHOOSELOGIN_COMBINED :
    		
    		WifiListNode mNode = mList.get(position);
    		
    		
    		
    		if (mNode.getContents() == WifiListNode.CONTAINS_SCANS) {
    			/* if encryption is required, return */
        		if (mNode.getEncryption() != Wifi.ENCRYPT_NONE && 
        				mNode.getEncryption() != Wifi.ENCRYPT_DETECTNONE) {
        			toastFromThread("Encrypted Network \nTry 'CONFIG' Option");
        			return;
        		}
    			this.chooseNetIdScan(mNode.getScan());
    		}
    		else if (mNode.getContents() != 0){
    			/* already configured */
    			this.chooseNetIdConfig(mNode.getConfig());
    		}
    		
    		break;
    	
		}
	
	}
	
	public void chooseNetIdScan(ScanResult mScan) {
		info = wifi.getConnectionInfo();
		mConfigs = (ArrayList<WifiConfiguration>)  wifi.getConfiguredNetworks();
		boolean mIsConfigured = false;
		
		/* exit if already connected */
		if (info.getSSID() != null && mScan.SSID.contentEquals( info.getSSID() )) return;
		
		WifiConfiguration mNewConfig = makeWifiConfig(Wifi.ENCRYPT_NONE ,mScan.SSID, "");
		/* check if configuration is already in the list */
		for (int i = 0; i < mConfigs.size(); i ++ ) {
			if (mConfigs.get(i).SSID.contains( mNewConfig.SSID )) {
				mIsConfigured = true;
				i = mConfigs.size();
			}
		}
		/* add network if necessary */
		if (!mIsConfigured) {
			wifi.addNetwork(mNewConfig);
		}
		/* search network again for new addition and connect*/
		WifiConfiguration mBestConfig = makeWifiConfig(Wifi.ENCRYPT_NONE, mScan.SSID, "");
		mConfigs = (ArrayList<WifiConfiguration>) wifi.getConfiguredNetworks();
		int mPriority = 50;    		
		for (int i = 0; i < mConfigs.size(); i ++ ) {
			if (mConfigs.get(i).SSID.contentEquals(mNewConfig.SSID)) {
				if (mConfigs.get(i).priority < mPriority) { 
					mBestConfig = mConfigs.get(i);
					mPriority = mConfigs.get(i).priority;
				}
			}
		}
		wifi.enableNetwork(mBestConfig.networkId, true);
		wifi.reassociate();
	}
	
	public void chooseNetIdConfig(WifiConfiguration mConfig) {
		info = wifi.getConnectionInfo();
		/* exit if already connected */
		if (mConfig.SSID.contentEquals("\""+ info.getSSID()+"\"")) {
			return;
		}
		
		wifi.enableNetwork(mConfig.networkId, true);
		wifi.reassociate();
	}
	
	
	
	public void menuHelperSmartAddConfig(WifiConfiguration mNewConfig) {
		mConfigs = (ArrayList<WifiConfiguration>) wifi.getConfiguredNetworks();
		boolean mIsConfigured = false;
		/* check if configuration is already in the list */
		for (int i = 0; i < mConfigs.size(); i ++ ) {
			if (mConfigs.get(i).SSID.contains( mNewConfig.SSID )) {
				mIsConfigured = true;
				i = mConfigs.size();
			}
		}
		
		/* add network if necessary */
		if (!mIsConfigured) {
			wifi.addNetwork(mNewConfig);
		}
		/* connect to highest priority config listing that matches ssid */
		WifiConfiguration mBestConfig = new WifiConfiguration();
		mConfigs = (ArrayList<WifiConfiguration>) wifi.getConfiguredNetworks();
		int mPriority = 50;  
		for (int i = 0; i < mConfigs.size(); i ++ ) {
			if (mConfigs.get(i).SSID.contentEquals(mNewConfig.SSID)) {
				if (mConfigs.get(i).priority < mPriority) { 
					mBestConfig = mConfigs.get(i);
					mPriority = mConfigs.get(i).priority;
					
				}
			}
		}
		wifi.enableNetwork(mBestConfig.networkId, true);
		wifi.reassociate();
		this.updateStatusLine();
	}
	
	public void menuHelperSmartForgetConfig( int mPos) {
		/* remove old configuration */
		if (mPos == -1) return;
		
		wifi.disableNetwork(mList.get(mPos).getConfig().networkId);
				
		wifi.removeNetwork(mList.get(mPos).getConfig().networkId);
		
		updateStatusLine();
	}
	
	private class ThreadHelper extends AsyncTask<Integer, Void, String> {
		
		@Override
		protected void onPreExecute() {
			mShouldLogin = false;
		}
		
		@Override
		protected String doInBackground(Integer... mPos) {
			String mResponse = "";
			
			int mPosition = mPos[0];
			
			//mShouldLogin = false;
			if ( mPosition == -1) return mResponse;
			
			mHandler.sendEmptyMessage(Wifi.DIALOG_SHOWPROGRESS_ID);
	    	
	    	chooseNetId(mPosition );
				    	
			String mChoiceString = new String();
			ArrayList<WifiListNode> mList = null;
			
			/* make sure we're looking at the same list as user */
			switch (mModeOfOp) {
			case Wifi.MODE_CHOOSELOGIN_CONFIG:
				mList = fillConfigList();
				break;

			case Wifi.MODE_CHOOSELOGIN_SCAN:
				mList = fillScanList();

				break;
			case Wifi.MODE_CHOOSELOGIN_COMBINED :
				mList = fillCombinedList();

				break;
			}
			
			/* do something to node of list */
			WifiListNode mNode = mList.get(mPosition);
			
    		if (mNode.getContents() == WifiListNode.CONTAINS_SCANS) {
    			mChoiceString = mNode.getScan().SSID.toString();

    			
    			
    		}
    		else if (mNode.getContents() != 0){
    			mChoiceString =  mNode.getConfig().SSID.toString() ;

    			
    		}
			
			
			if (!mShouldLogin) mHandler.sendEmptyMessage(Wifi.DIALOG_STOPPROGRESS_ID);
			
			
			
			return mResponse;
		}
		@Override
		protected void onPostExecute( String mResult) {
			if (mShouldLogin) {
				mTimer = new ThreadHelperTimer();
	        	mTimer.execute(new Integer[] {mSecondTimer});
	        	wifi.startScan();   
			}
		}
	}
	
	
	
	
	
	private class ThreadHelperTimer extends AsyncTask<Integer, Void, String> {
		
		@Override
		protected void onPreExecute() {
			mCanShowStartDialog = false;
			mCanSelect = false;
		}
		
		@Override
		protected String doInBackground( Integer... mSeconds) {
			String mResponse = "";
			
        	try {
				Thread.sleep(mSeconds[0] * 1000); // 10 secs
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			} 
        	
			return mResponse;
		}
		@Override
		protected void onPostExecute(String mResult) {
			mShouldLogin = false;
			mHandler.sendEmptyMessage(Wifi.DIALOG_STOPPROGRESS_ID);
			mHandler.sendEmptyMessage(Wifi.DIALOG_TIMEOUT_ID);

		}
	}
	
	public void toastFromThread(String mS) {
		Message mM = new Message();
		mM.what = Wifi.DIALOG_SHOWTOAST_ID;
		mM.obj = new String(mS);
		mHandler.sendMessage(mM);
	}
	
}